﻿using CRM.Extensions;
using CRM.Interface;
using CRM.Models;
using CRM.Models.SeedData;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq.Expressions;
using CRM.Models.Email;
using CRM.Models.GlobalSearch;
using CRM.Models.Mailjet;
using CRM.Models.SocialMarketing;

namespace CRM
{
    /* PM
         切换迁移环境
            $env:ASPNETCORE_ENVIRONMENT = ""
            $env:ASPNETCORE_ENVIRONMENT = "Dev_SQLite"
            # 指定$env:ASPNETCORE_ENVIRONMENT或$env:DOTNET_ENVIRONMENT都可以达到切换效果
            $env:DOTNET_ENVIRONMENT = ""
            $env:DOTNET_ENVIRONMENT = "Dev_SQLite"
            # 保险起见可以ps连续赋值
            $env:ASPNETCORE_ENVIRONMENT = $env:DOTNET_ENVIRONMENT = ""            #默认测试环境
            $env:ASPNETCORE_ENVIRONMENT = $env:DOTNET_ENVIRONMENT = "Dev_SQLite"  #Dev_SQLite环境
         控制台
         https://docs.microsoft.com/zh-cn/ef/core/cli/powershell#add-migration
         添加迁移文件/初始化
          Add-Migration -OutputDir Migrations\Debug\MySQL -Name <String>                #Default
          Add-Migration -OutputDir Migrations\Debug\SQLite [name]                       #Dev_SQLite
          Add-Migration -OutputDir Migrations\Debug\SQLite init                         #Dev_SQLite
         回滚迁移
          Remove-Migration                                                        #会依赖数据库记录进行,无需指定输出目录？
         更新数据库/执行迁移/没有数据库会自动创建
          Update-Database
         删库
          Drop-Database
         生成SQL脚本，来手动迁移
          Script-Migration -Context Label
         获取帮助
          get-help entityframework
    */
    // dotnet ef tools
    // 安装 dotnet tool install --global dotnet-ef
    // https://docs.microsoft.com/zh-cn/ef/core/cli/dotnet
    // 添加迁移 
    //  dotnet ef migrations add -o Migrations\MySQL <String>
    //  dotnet ef migrations add -o Migrations\Debug\SQLite <String>
    //  dotnet ef migrations add -o Migrations\Production <String>
    // 更新数据库 dotnet ef database update


    public class MyDbContext :
        IdentityDbContext<User, Role, int, UserClaim,
            IdentityUserRole<int>,
            IdentityUserLogin<int>,
            RoleClaim,
            IdentityUserToken<int>>
    {
        public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
        {
            this.HandleDataChanged();
        }

        //public MyDbContext(DbContextOptions options) : base(options)
        //{
        //    Console.WriteLine("MyDbContext(DbContextOptions options)");
        //}
        public DbSet<Test> Tests { get; set; }
        public override DbSet<User> Users { get; set; }
        public override DbSet<Role> Roles { get; set; }
        public DbSet<UserLoginLog> UserLoginLogs { get; set; }
        public DbSet<UserGroup> UserGroup { get; set; }
        public DbSet<Company> Company { get; set; }
        public DbSet<Validity> Validity { get; set; }
        public DbSet<Menu> Menus { get; set; }
        public DbSet<CustomerLabel> CustomerLabel { get; set; }
        public DbSet<CustomerGroup> CustomerGroup { get; set; }
        public DbSet<CustomerSource> CustomerSource { get; set; }
        public DbSet<CustomerFollow> CustomerFollow { get; set; }
        public DbSet<CustomerCompany> CustomerCompany { get; set; }
        public DbSet<Customer> Customer { get; set; }
        public DbSet<CustomerOperationLog> CustomerOperationLog { get; set; }
        public DbSet<SocialMarketingTask> SocialMarketingTasks { get; set; }
        public DbSet<SocialMarketingTaskOperationLog> SocialMarketingTaskOperationLogs { get; set; }

        public DbSet<EmailMarketing> EmailMarketing { get; set; }
        public DbSet<RushMailLink> RushMailLinks { get; set; }
        public DbSet<EmailTemplate> EmailTemplate { get; set; }
        public DbSet<EmailSendHistory> EmailSendHistory { get; set; }
        public DbSet<EmailSenderName> EmailSenderNames { get; set; }
        public DbSet<EmailBlackList> EmailBlackLists { get; set; }
        public DbSet<Oem> Oem { get; set; }
        public DbSet<OemCompany> OemCompany { get; set; }
        public DbSet<EmailConfig> EmailConfig { get; set; }
        public DbSet<RuleTemplate> RuleTemplate { get; set; }
        public DbSet<UserLog> UserLog { get; set; }
        public DbSet<EmailConfigGroup> EmailConfigGroup { get; set; }
        public DbSet<EmailVerify> EmailVerifies { get; set; }
        public DbSet<EmailVerifyLog> EmailVerifyLogs { get; set; }
        public DbSet<WebhookLog> WebhookLog { get; set; }
        public DbSet<WebhookEventDetails> WebhookEventDetails { get; set; }
        public DbSet<KeywordsDomain> KeywordsDomains { get; set; }
        public DbSet<ApiInvokedLog> ApiInvokedLogs { get; set; }
        public DbSet<Nation> Nations { get; set; }

        public DbSet<CompanyPointsConfig> CompanyPointsConfig { get; set; }
        public DbSet<PointsConsumptionLog> PointsConsumptionLog { get; set; }

        public DbSet<EmailMarkeingLog> EmailMarkeingLog { get; set; }

        #region  customsData
        public DbSet<Commodity> Commodity { get; set; }
        public DbSet<ExportCommodity> Exportcommodity { get; set; }
        public DbSet<ImportCommodity> ImportCommodity { get; set; }
        public DbSet<Province> Province { get; set; }

        public DbSet<TradeData> Tradedata { get; set; }

        public DbSet<TradeMode> Trademode { get; set; }

        public DbSet<TradePartner> Tradepartner { get; set; }

        public DbSet<UOMAdjust> Uomadjustment { get; set; }

        #endregion
        public DbSet<BuyerData> BuyersData { get; set; }

        // protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        // {
        //
        //     Console.WriteLine("OnConfiguring");
        //     base.OnConfiguring(optionsBuilder);
        //
        //     optionsBuilder.LogTo(Console.WriteLine, new[] { RelationalEventId.CommandExecuted }, LogLevel.Information);
        //     //System.Diagnostics.Debug.Print("x");
        // }


        public DbSet<BuyerDataPullLog> BuyerDataPullLog { get; set; }
        public DbSet<VerifyCodeLog> VerifyCodeLog { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            // modelBuilder.Entity<EmailConfigGroup>().HasMany(g => g.EmailConfigs)
            //     .WithOne(e => e.Group).OnDelete(DeleteBehavior.SetNull);
            foreach (var entityType in modelBuilder.Model.GetEntityTypes())
            {
                if (!entityType.ClrType.IsAssignableTo(typeof(ISoftDelete))) continue;
                var parameter = Expression.Parameter(entityType.ClrType);
                var ownedModelType = parameter.Type;
                var ownedAttribute = Attribute.GetCustomAttribute(ownedModelType, typeof(OwnedAttribute));
                if (ownedAttribute == null)
                {
                    var propertyMethodInfo = typeof(EF).GetMethod("Property").MakeGenericMethod(typeof(bool));
                    var isDeletedProperty =
                        Expression.Call(propertyMethodInfo, parameter, Expression.Constant("IsDeleted"));
                    var compareExpression = Expression.MakeBinary(ExpressionType.Equal, isDeletedProperty,
                        Expression.Constant(false));
                    var lambda = Expression.Lambda(compareExpression, parameter);
                    modelBuilder.Entity(entityType.ClrType).HasQueryFilter(lambda);
                }
            }

            modelBuilder.Entity<Oem>(b =>
            {
                b.Property(x => x.ShowLoginLogo).HasDefaultValue(true);
                b.Property(x => x.ShowIndexLogo).HasDefaultValue(true);
                b.Property(x => x.ShowIndexContent).HasDefaultValue(true);
                b.OwnsOne(x => x.EmailSettings, s =>
                {
                    s.Property(x => x.EmailPlatform).HasDefaultValue(EmailPlatform.Mailjet);
                    s.Property(x => x.UseIndependentRushmail).HasDefaultValue(false);
                    s.Property(x => x.UseIndependentMailjet).HasDefaultValue(false);
                });
            });

            // modelBuilder.RemoveForeignKeys();
            modelBuilder.SeedData();
        }

        public override void Dispose()
        {
            this.RemoveDataChanged();
            base.Dispose();
        }
    }
}